/******************************************************************************\
 *
 * File Name   : oslite.c
 *
 * Description : os envelop for fast eviroment migration
 *
 *
\******************************************************************************/
//#include "stdafx.h"
#include "oslite.h"
#if defined(WIN32)

#endif

#if defined LINUX


typedef struct
{
	pthread_mutex_t		Mutex;
	pthread_cond_t		Condition;
	int								SemCount;
}LinuxSemaphore_t;

#endif

void xx_Free(void *ptr);
unsigned int XX_GetClock(void);
void *xx_Malloc(int size);

#include "oslite.h"
#if defined(WIN32)
U32 logTrace;
#endif


int OS_GetTaskPriority (OS_Task_t Task,int *Priority){
#ifdef WIN32
		return GetThreadPriority((HANDLE)Task);
#endif

#ifdef LINUX
	  struct sched_param   param;
	  int				   policy;
	  int				   rc;
	  rc = pthread_getschedparam(Task, &policy, &param);
	  *Priority = param.sched_priority;
	  
	  return rc;		
#endif

}


int OS_SetTaskPriority (OS_Task_t Task,int Priority){
#ifdef WIN32
	SetThreadPriority((HANDLE)Task,Priority);
	return 0;
#endif
#ifdef LINUX
  struct sched_param   param;
  int                  policy;
  int                  rc;
  rc = pthread_getschedparam(Task, &policy, &param);
  param.sched_priority = Priority ;
  rc = pthread_setschedparam(Task, policy, &param);
  return rc;

#endif
	return 0;

}

OS_Task_t  OS_TaskCreate(U32 StackSize,char *TaskName,OS_TaskFunc_t TaskFunc,int Priority,void *Param){
#if  defined(WIN32)
	U32 ThreadId;
	OS_Task_t task ;
    //*task = _beginthread( function, stack_size, 0);
	task = (OS_Task_t)CreateThread(
		0,										// pointer to security attributes
		StackSize,								// initial thread stack size
		(LPTHREAD_START_ROUTINE) TaskFunc,       // pointer to thread function
		Param,									 // argument for new thread
		CREATE_SUSPENDED,									 // creation flags
		(unsigned long *)&ThreadId                                // pointer to receive thread ID
		);

	SetThreadPriority((HANDLE)task,Priority);
	ResumeThread((void*)task);
	return task;
#endif
#if  defined(TI_BIOS)
	 TSK_Attrs  Attrs ={0};
	 OS_Task_t task ;
	  Attrs.priority  = Priority;
	  Attrs.stack	  = 0;
	  Attrs.stacksize = StackSize;
	  if(sizeof(Attrs.name ) > strlen(TaskName))
		strcpy(Attrs.name ,TaskName);
	  Attrs.stackseg   = OS_GetPartition(NCACHED_PARTITION);
	  Attrs.exitflag =1;
	  Attrs.initstackflag =1;

	  task = TSK_create((Fxn)TaskFunc,&Attrs,Param);
	  return task;
#endif
#if defined(LINUX)
	pthread_t hthread;
	int rc;
	pthread_attr_t attr;
	rc = pthread_attr_init(&attr);
	rc = pthread_attr_setstacksize(&attr, StackSize);
//    rc = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    rc = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

	rc = pthread_create(&hthread, &attr, (void*(*)(void*))TaskFunc, Param);
	if(rc != 0){
		return 0;
	}
    return (OS_Task_t )hthread;
#endif
}


int OS_TaskWait(OS_Task_t Task,U32 TimeOut){
#ifdef WIN32
U32 Time =TimeOut;
U32  terminat;

	while(GetExitCodeThread((HANDLE)Task,(unsigned long *)&terminat)){

		if((terminat != STILL_ACTIVE) )
			return 0;

		if(TIMEOUT_INFINITY != TimeOut)
		{
			Time-=1;
			if(Time<1)
				break;
		}
		if(TIMEOUT_IMMEDIATE == TimeOut)
			break;
		OS_MSleep(1);
	}

#endif
#if defined(TI_BIOS)
	while(1){
		TSK_Stat Stat;
		U32 Time =TimeOut;

		TSK_stat(Task, &Stat);
		if(Stat.mode == TSK_TERMINATED){
			return 0;
		}

		if((U32)TIMEOUT_INFINITY != TimeOut)
		{
			Time-=1;
			if(Time<1)
				break;
		}
		if(TIMEOUT_IMMEDIATE == TimeOut)
			break;
		OS_MSleep(1);
	}
#endif

#if defined(LINUX)
	U32 Time =TimeOut;
	while(OS_IsTaskRunning(Task)){
		if(TIMEOUT_INFINITY != TimeOut)
		{
			Time-=10;
			if(Time<10)
				break;
		}
		if(TIMEOUT_IMMEDIATE == TimeOut)
			break;

		OS_MSleep(10);
	}

#endif
	return -1;
}



int OS_IsTaskRunning(OS_Task_t Task){
#if  defined(WIN32)
	if(GetThreadPriority((HANDLE)Task) != THREAD_PRIORITY_ERROR_RETURN)
		return 1;
#endif

#if defined(LINUX)
	if(pthread_kill(Task, 0) == 0) return 1;
#endif
	return 0;
}



void OS_TaskDelete(OS_Task_t Task){
#ifdef WIN32
	if(Task){
		OS_TaskWait(Task,  TIMEOUT_INFINITY);
		CloseHandle((HANDLE)Task);
	}
#endif
#if defined(TI_BIOS)
	if(Task){
		TSK_delete(Task);
	}
#endif

#if defined(LINUX)
	int rc;
	
	//OS_TaskWait(Task,  TIMEOUT_INFINITY);
	rc = pthread_join(Task,0);
	rc = pthread_detach(Task);
#endif
}

OS_Task_t  OS_TaskGetSelf(void){
#if defined(WIN32)
	return (OS_Task_t)GetCurrentThread();
#endif
#if defined(TI_BIOS)
	OS_Task_t curtask;
	curtask = TSK_self();
	return curtask;
#endif
#if defined(LINUX)
	return pthread_self();
#endif

}

int OS_IsTaskEqual(OS_Task_t task1,OS_Task_t task2){
#if defined(LINUX)	
	return pthread_equal(task1,task2);
#endif	
}


int OS_SetSignal(OS_Semaphore_t Semaphore){
#ifdef WIN32
	long prev;
	int err;
	err = ReleaseSemaphore((HANDLE)Semaphore,1,&prev);

	if(err ) return 0;
	dbg_assert(0);

#endif
#if  defined(TI_BIOS)
		SEM_post(Semaphore);
#endif
#if defined(LINUX)
  LinuxSemaphore_t  *pSem = (LinuxSemaphore_t  *)Semaphore;
//  fprintf(stderr,"set cond++: count(%d)\n\r",pSem->SemCount);
  pthread_mutex_lock	(&pSem->Mutex		);
  pSem->SemCount++;
	pthread_cond_signal	(&pSem->Condition	);
//	fprintf(stderr,"set cond--: count(%d)\n\r",pSem->SemCount);
	pthread_mutex_unlock(&pSem->Mutex		);
#endif

	return 0;
}


int OS_GetSignalCount(OS_Semaphore_t Semaphore){
#if defined(LINUX)
		LinuxSemaphore_t  *pSem = (LinuxSemaphore_t  *)Semaphore;
		return pSem->SemCount;
#endif	
}

int OS_WaitSignal(OS_Semaphore_t Semaphore,OS_Semaphore_t Sig,U32 Time){
#ifdef WIN32
	int err=0;
	if(Semaphore ==0) return -1;
	if(Time == TIMEOUT_INFINITY)
		err = WaitForSingleObject((HANDLE)Semaphore,INFINITE);
	else{
		err = WaitForSingleObject((HANDLE)Semaphore,Time);
	}
	if(err == WAIT_OBJECT_0)
		return 0;
	return OS_TIMEOUT;
#endif
#if defined(TI_BIOS)
    int err;
	if(Semaphore ==0) return -1;
	if(Time == (U32)TIMEOUT_INFINITY){
		err = SEM_pend(Semaphore,SYS_FOREVER);
	}
	else{
		err = SEM_pend(Semaphore, Time);
	}

	if(err != 0) return 0;

		return OS_TIMEOUT;

#endif

#if defined(LINUX)
	LinuxSemaphore_t  *pSem = (LinuxSemaphore_t  *)Semaphore;
	LinuxSemaphore_t  *pSig = (LinuxSemaphore_t  *)Sig;

	int rc;

	//rc = pthread_mutex_lock	(&pSem->Mutex);
	if(Time == TIMEOUT_INFINITY){
		rc = pthread_cond_wait(&pSig->Condition, &pSem->Mutex);
	}

	else{
		struct timespec timeout={0};
		unsigned int StartTime;
		StartTime       = OS_GetKHClock() + Time;
		timeout.tv_sec	= StartTime/1000;
		timeout.tv_nsec	= (StartTime % 1000) * 1000 ;
        rc =  pthread_cond_timedwait(&pSig->Condition,  &pSem->Mutex, &timeout);

	}


	//pthread_mutex_unlock(&pSem->Mutex		);
	if(rc== ETIMEDOUT)
		return OS_TIMEOUT;

	return 0;
#endif
}

int OS_WaitSemaphore(OS_Semaphore_t Semaphore){
#ifdef WIN32
	int err =	WaitForSingleObject((HANDLE)Semaphore,INFINITE);
	if(err == WAIT_OBJECT_0)
		return 0;
	return OS_TIMEOUT;

#endif
#if defined(TI_BIOS)
	int err;
	err = SEM_pend(Semaphore,SYS_FOREVER);
	if(err != 0)
		return 0;
	return OS_TIMEOUT;
#endif

#if defined(LINUX)
	LinuxSemaphore_t  *pSem = (LinuxSemaphore_t  *)Semaphore;
	int rc;

	rc = pthread_mutex_lock(&pSem->Mutex);
	assert(rc ==0);
#if 0	
	if(pSem->SemCount <= 0){
		rc = pthread_cond_wait(&pSem->Condition, &pSem->Mutex);
	}
	pSem->SemCount--;

	rc = pthread_mutex_unlock(&pSem->Mutex);
	assert(rc ==0);
#endif
	return 0;

#endif
}

int OS_SetSemaphore(OS_Semaphore_t Semaphore){
#ifdef WIN32
	long prev;
	int err;
	err =ReleaseSemaphore((HANDLE)Semaphore,1,&prev);
	if(err ) return 0;
	return -1;
#endif
#if defined(TI_BIOS)
	SEM_post(Semaphore);
#endif

#if defined(LINUX)
	 LinuxSemaphore_t  *pSem = (LinuxSemaphore_t  *)Semaphore;
	  int rc;
	rc = pthread_mutex_unlock(&pSem->Mutex);
	assert(rc==0);



#endif

  return 0;
}

OS_Semaphore_t OS_AllocSemaphore(void){
#ifdef WIN32
	return (OS_Semaphore_t)CreateSemaphore(0,1,100,0);
#endif
#if defined(TI_BIOS)
	return SEM_create(1,0);
#endif

#if defined(LINUX)
	int rc;
	LinuxSemaphore_t  *pSem;
	pSem     = (LinuxSemaphore_t *)OS_MemAlloc(sizeof(LinuxSemaphore_t));
	memset((void*)pSem,0,sizeof(*pSem));
	rc = pthread_mutex_init(&pSem->Mutex, NULL);
	assert(rc==0);

	rc = pthread_cond_init(&pSem->Condition, NULL);
	assert(rc==0);
    pSem->SemCount = 1;
	return (OS_Semaphore_t)pSem;
#endif
}

int OS_DeleteSemaphore(OS_Semaphore_t Semaphore){
#ifdef WIN32
	if(Semaphore==0) return -1;
	CloseHandle((HANDLE)Semaphore);
	return 0;
#endif
#if defined(TI_BIOS)
	SEM_delete(Semaphore);
	return 0;
#endif

#if defined(LINUX)
	 LinuxSemaphore_t  *pSem = (LinuxSemaphore_t  *)Semaphore;
	 pthread_mutex_destroy(&pSem->Mutex);
	 pthread_cond_destroy(&pSem->Condition);
	 OS_MemFree((void*)pSem);
	 return 0;
#endif

}

OS_Semaphore_t OS_AllocSignal(void){
#ifdef WIN32
	return (U32)CreateSemaphore(0,0,100,0);
#endif
#if defined(TI_BIOS)
	return SEM_create(0,0);
#endif
#if defined(LINUX)
	int rc=0;
	LinuxSemaphore_t  *pSem;
	pSem     = (LinuxSemaphore_t  *)OS_MemAlloc(sizeof(LinuxSemaphore_t));
	assert(pSem !=0);
	memset((void*)pSem,0,sizeof(LinuxSemaphore_t));

	//pSem->Mutex = PTHREAD_MUTEX_INITIALIZER;
	rc = pthread_mutex_init(&pSem->Mutex, NULL);
	assert(rc ==0);
	//pSem->Condition = PTHREAD_COND_INITIALIZER;
	rc = pthread_cond_init(&pSem->Condition, NULL);
	assert(rc ==0);
	pSem->SemCount = 0;
	return (OS_Semaphore_t)pSem;
#endif
}

int OS_DeleteSignal(OS_Semaphore_t Semaphore){
#ifdef WIN32
	CloseHandle((HANDLE)Semaphore);
	return 0;
#endif

#if defined(TI_BIOS)
	SEM_delete(Semaphore);
	return 0;
#endif
#if defined(LINUX)
	 LinuxSemaphore_t  *pSem = (LinuxSemaphore_t  *)Semaphore;
	 pthread_mutex_destroy(&pSem->Mutex);
	 pthread_cond_destroy(&pSem->Condition);
	 OS_MemFree((void*)pSem);
	 return 0;
#endif
}

void OS_FastCopy(void *Dst,void *Src,U32 Size){
	memcpy(Dst,Src,Size);
}

void OS_FastFill(void *Dest,U8 Value,U32 Size){
	memset(Dest,Value,Size);
}


void OS_MSleep(U32 ms){
#if defined(WIN32)
	Sleep(ms);
#endif
#if defined(TI_BIOS)
	TSK_sleep(ms );
#endif
#if defined(LINUX)
struct timespec timeOut,remains;
	timeOut.tv_sec = ms/1000;
	timeOut.tv_nsec = (ms % 1000) * 1000*1000;
	nanosleep(&timeOut, &remains);
#endif
}

void OS_USleep(U64 us){
#if defined(WIN32)
	Sleep(us/1000);
#endif
#if defined(TI_BIOS)
	TSK_sleep(us);
#endif
#if defined(LINUX)
	struct timespec timeOut,remains;
	timeOut.tv_sec = us/1000000LL;
	timeOut.tv_nsec = (us % 1000000LL)*1000LL;
	nanosleep(&timeOut, &remains);
#endif

}


#include <time.h>
U32 OS_GetKHClock(void){
#ifdef WIN32

	return clock();
#endif
#if defined(TI_BIOS)
	return CLK_getltime();
#endif
#if defined(FREESCALE_NETCOMM)
 return XX_GetClock();
#endif
#if defined(LINUX)
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return (int64_t)tv.tv_sec * 1000 + tv.tv_usec/1000;

#endif
}



int64_t OS_GetMHClock(void){
#ifdef WIN32
	return (int64_t)clock() *1000;
#endif
#if defined(TI_BIOS)
	return CLK_getltime();
#endif
#if defined(FREESCALE_NETCOMM)
 return XX_GetClock();
#endif
#if defined(LINUX)
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return tv.tv_sec * 1000000 + tv.tv_usec;
#endif
}



/**
 * @return NTP 64-bits timestamp in host byte order.
 */
uint64_t OS_NTPtime64 (void)
{
    struct timespec ts;
#ifdef WIN32
    clock_gettime (CLOCK_REALTIME, &ts);
#else
    {
        struct timeval tv;
        gettimeofday (&tv, NULL);
        ts.tv_sec = tv.tv_sec;
        ts.tv_nsec = tv.tv_usec * 1000;
    }
#endif

    /* Convert nanoseconds to 32-bits fraction (232 picosecond units) */
    uint64_t t = (uint64_t)(ts.tv_nsec) << 32;
    t /= 1000000000;


    /* There is 70 years (incl. 17 leap ones) offset to the Unix Epoch.
     * No leap seconds during that period since they were not invented yet.
     */
   // assert (t < 0x100000000);
    t |= ((70LL * 365 + 17) * 24 * 60 * 60 + ts.tv_sec) << 32;
    return t;
}




U32 OS_GetChipID(void){

return 0;
}

U32 m_memsum=0;
void* OS_MemoryAllocate(OS_Partition_t partition,int size){

#if defined(WIN32) || defined(LINUX)
	return malloc(size);
#endif
#if defined(TI_BIOS)
	U32 *p;
	p = MEM_alloc(partition, size+4, 4);
	m_memsum+= (size+4);

	if(p==0){
		dbg_assert(p!=0);
	}
	*p = size;
	p++;
	return (void*)p;
#endif

#if defined(FREESCALE_NETCOMM)
 return xx_Malloc(size);
#endif
return 0;
}


void *OS_MemoryAllocateAlliment(OS_Partition_t partition,int Size,int Alignment,void **pBase){
U8 *pAlignment;
U32 Base;
	Base =  (U32)OS_MemoryAllocate( partition,Size + (1<<Alignment));
	pAlignment = (U8*)( Base + ((1<<Alignment) - (Base % (1<<Alignment))));
	*pBase     = (void*)Base;
	return pAlignment;
}


void *OS_MemoryReallocate(OS_Partition_t partition,void* block,int size){
#if defined(WIN32) || defined(LINUX)
	return realloc(block,size);
#endif
#if defined(TI_BIOS)
	if(block==0){
		return OS_MemoryAllocate(partition,size);
	}
	else{
		void *ptr = OS_MemoryAllocate(partition,size);
		if(ptr){
			U32 *p = (U32*)block;
			p--;
			memcpy(ptr,block,min(*p,size));
		}
		OS_MemoryFree(partition,block);
		return ptr;
	}
#endif
#if defined(FREESCALE_NETCOMM)
#endif
 return 0;
}

void OS_MemoryFree(OS_Partition_t partition,void* block){
#if defined(WIN32) || defined(LINUX)
	free(block);
#endif
#if defined(TI_BIOS)
	U32 *p = (U32*)block;
	p--;
	m_memsum -= *p;
	MEM_free(partition,(void*)p,*p);
#endif
#if defined(FREESCALE_NETCOMM)
xx_Free(block);
#endif

}

void *OS_MemAlloc(int size){
	return malloc(size);
}

void OS_MemFree(void* pMem){
	free(pMem);
}


OS_Partition_t   OS_GetPartition(PartitionID_t ID){
	//OS_Partition_t part =0;

#if defined(WIN32)
	return 0;
#endif

#if defined(TI_BIOS)
extern U32 L2_Heap;
extern U32 DDR2_Heap;
//	return NCACHED_SEG;
//	return CACHED_SEG;

	switch(ID){
	case CACHED_PARTITION	:
		return DDR2_Heap;

	case NCACHED_PARTITION	:
		return L2_Heap;
	default :
		return L2_Heap;

	}
//	return 0;
#endif
#if defined(FREESCALE_NETCOMM)
 return 0;
#endif
return 0;
}



#if defined(WIN32)
#define ISR_TABLE_SIZE 100
typedef struct{
	ISRHandler_t ISR;
	U32          Mask;
	U32          Flag;
	U32          EnableFlag;
	U32          InterruptLevel;
	void         *pParam;
}ISRObj_t;

ISRObj_t ISRTable[ISR_TABLE_SIZE]={0};
#endif // WIN32

int OS_InterruptInstall(int InterruptNumber,int InterruptLevel,ISRHandler_t ISR,void*pParam){
#if defined(WIN32)
	ISRTable[InterruptNumber].InterruptLevel = InterruptLevel;
	ISRTable[InterruptNumber].ISR			 = ISR;
	ISRTable[InterruptNumber].pParam		 = pParam;
#endif

#if defined(TI_BIOS)

#endif
	return 0;
}

int OS_InterruptEnable(int InterruptNumber,int Enable){
#if defined(WIN32)
	ISRTable[InterruptNumber].EnableFlag = Enable;
#endif
#if defined(TI_BIOS)

#endif
	return 0;
}

void OS_InterruptShoot(int InterruptNumber){
#if defined(WIN32)

//	if(ISRTable[InterruptNumber].Flag & ISRTable[InterruptNumber].Mask && ISRTable[InterruptNumber].EnableFlag){
		if(ISRTable[InterruptNumber].ISR)
			ISRTable[InterruptNumber].ISR(ISRTable[InterruptNumber].pParam);
//	}
#endif
}

void OS_InterruptSetMask(int InterruptNumber,U32 Mask){
#if defined(WIN32)
	ISRTable[InterruptNumber].Mask = Mask;
#endif
}

U32 OS_InterruptGetEventFlag(int InterruptNumber){
#if defined(WIN32)
	return ISRTable[InterruptNumber].Mask & ISRTable[InterruptNumber].Flag;
#endif
 return 0;
}


void OS_InterruptClear(int InterruptNumber,U32 Mask){
#if defined(WIN32)
	ISRTable[InterruptNumber].Flag &= ~Mask;
#endif
}

void OS_InterruptSetEvent(int InterruptNumber , U32 Event){
#if defined(WIN32)
	ISRTable[InterruptNumber].Flag |= Event;
#endif
}



int OS_GetSystemTime(unsigned int *SystemTime){
#if defined(WIN32)
	//tm * ptm;
//	time_t rawtime;

	if(SystemTime){
		time((time_t*)SystemTime);
		return 0;
	}

#if 0
	ptm = gmtime ( &rowtime);

	SystemTime->sec		= ptm->tm_sec;
	SystemTime->min		= ptm->tm_min;
	SystemTime->hour	= ptm->tm_hour;
	SystemTime->mday	= ptm->tm_mday;
	SystemTime->mon 	= ptm->tm_mon ;
	SystemTime->year	= ptm->tm_year;
#endif
//	time.
#endif
#if defined(LINUX)
	//tm * ptm;
//	time_t rawtime;

	if(SystemTime){
		time((time_t*)SystemTime);
		return 0;
	}

#if 0
	ptm = gmtime ( &rowtime);

	SystemTime->sec		= ptm->tm_sec;
	SystemTime->min		= ptm->tm_min;
	SystemTime->hour	= ptm->tm_hour;
	SystemTime->mday	= ptm->tm_mday;
	SystemTime->mon 	= ptm->tm_mon ;
	SystemTime->year	= ptm->tm_year;
#endif

#endif
	return 0;
}

int OS_SetSystemTime(unsigned int SystemTime){
	return 0;
}

typedef struct {
	unsigned int useflag;
	unsigned int inptr;
	unsigned int outptr;
	OS_Semaphore_t sig;
	char key[64];
	void ** fifo;
	int  fifosize;
}FifoElement_t;


static FifoElement_t *m_fifolist=0;
static int m_fifosize=0;
static OS_Semaphore_t m_fifosem=0;

int OS_FifoInit(int NumOfFifo){
	if(m_fifolist ==0)
		m_fifolist = (FifoElement_t *)OS_MemAlloc(NumOfFifo * sizeof(FifoElement_t));
	if(m_fifolist){
		memset((void*)m_fifolist,0,NumOfFifo * sizeof(FifoElement_t));
		m_fifosize = NumOfFifo;
		m_fifosem = OS_AllocSemaphore();
		return 0;
	}
	return OS_ERROR_NO_MEMORY;
}

void OS_FifoTerm(void){
	int i;
	if(m_fifolist !=0){
		for(i=0;i<m_fifosize;i++){
			if(m_fifolist[i].fifo !=0){
				OS_FifoDelete((OS_Fifo_t)&m_fifolist[i]);
			}
		}
		OS_MemFree((void*)m_fifolist);
		m_fifolist =0;
	}
	if(m_fifosem)
		OS_DeleteSemaphore(m_fifosem);
	m_fifosem=0;

}

OS_Fifo_t OS_FifoCreate(char *key,int FifoSize){
	int i;
	for(i=0;i<m_fifosize;i++){
		if(m_fifolist[i].fifo ==0)
			break;
	}

	if(i==m_fifosize)
		return 0;

	memset((void*)&m_fifolist[i],0,sizeof(m_fifolist[i]));
	m_fifolist[i].fifo = (void**)OS_MemAlloc(sizeof(void*) * FifoSize);
	if(m_fifolist[i].fifo ==0)
		return 0;
	m_fifolist[i].fifosize = FifoSize;
	m_fifolist[i].sig = OS_AllocSignal();
	strcpy(m_fifolist[i].key,key);
	return (OS_Fifo_t)&m_fifolist[i];
}

void OS_FifoDelete(OS_Fifo_t fifo){
	FifoElement_t *pFifo = (FifoElement_t *)fifo;
	pFifo->useflag = 0;
	if(pFifo->sig !=0)
		OS_DeleteSignal(pFifo->sig);
	pFifo->sig =0;
	if(pFifo->fifo !=0)
		OS_MemFree(pFifo->fifo);
	pFifo->fifo =0;
}

OS_Fifo_t OS_FifoConnect(char *key){
	int i;
	for(i=0;i<m_fifosize;i++){
		if((m_fifolist[i].fifo !=0) && (strcmp(m_fifolist[i].key,key)==0))
			break;
	}
	if(i==m_fifosize)
		return 0;

	return (OS_Fifo_t )&m_fifolist[i];
}


int OS_FifoGet(OS_Fifo_t hfifo,void **msg){
	int err=0;
#if 0	

	FifoElement_t *pFifo = (FifoElement_t *)hfifo;
	if(pFifo && pFifo->sig){
		err = OS_WaitSignal(pFifo->sig,TIMEOUT_INFINITY);
	if(m_fifosem)
		OS_WaitSemaphore(m_fifosem);
		*msg = pFifo->fifo[pFifo->outptr];
		pFifo->outptr = (pFifo->outptr + 1) % pFifo->fifosize;
	if(m_fifosem)
		OS_SetSemaphore(m_fifosem);
	}
#endif	
	return err;
}

int OS_IsFifoFull(OS_Fifo_t hfifo){
	FifoElement_t *pFifo = (FifoElement_t *)hfifo;
	int full=0;
	//if(m_fifosem)
	//	OS_WaitSemaphore(m_fifosem);

	if(((pFifo->inptr + 1) % pFifo->fifosize) == pFifo->outptr)
		full =1;

	//if(m_fifosem)
	//	OS_SetSemaphore(m_fifosem);

	return full;
}


int OS_FifoPut(OS_Fifo_t hfifo,void *msg){
	FifoElement_t *pFifo = (FifoElement_t *)hfifo;
	int i,N=50;
	int Err=0;
    if(m_fifosem)
		OS_WaitSemaphore(m_fifosem);
	for(i=0;i<N;i++){
		if(OS_IsFifoFull(hfifo))
			OS_MSleep(10);
		else
			break;
	}
	if(i<N){
		pFifo->fifo[pFifo->inptr] = msg;
		pFifo->inptr = (pFifo->inptr + 1) % pFifo->fifosize;
		OS_SetSignal(pFifo->sig);
	}
	else {
		fprintf(stderr,"%s Error Fifo Full  \n",__func__);
		Err = -1;
		}
	if(m_fifosem)
		OS_SetSemaphore(m_fifosem);
	return Err;
}

OS_Handle_t     OS_CreateProcess(char *processname,char *arglist[]){
	int err;
	pid_t pid = fork();
	if(pid ==0){  // chield process
		err = execv(processname, arglist);
		//fprintf(stderr,"after execv %d\n\r",err);
		 exit( -1 );
	}
	else{
		//wait(&status);
		//fprintf(stderr,"wait execv %d\n\r",pid);
		return pid;
	}
}



int OS_WaitForProcess(OS_Handle_t pid){
#if defined(LINUX)
	int status=0;
	OS_Handle_t newpid=0;
	int options =0; //WCONTINUED ;

	newpid = waitpid(pid,&status,options);
	return status;
#endif
}

int OS_GetProcessState(OS_Handle_t pid){
#if defined(LINUX)
	int status=0;
	OS_Handle_t newpid=0;
	int options = WNOHANG ;

	newpid = waitpid(pid,&status,options);
	return status;
#endif
}


int  OS_System(char *commandline){
	#if defined(LINUX)
	return system(commandline);
	#endif
}



/**
 * Wakes up all threads (if any) waiting on a condition variable.
 * @param p_cond condition variable
 */
void OS_cond_broadcast (OS_cond_t *p_condvar)
{
#if defined (LINUX)
    pthread_cond_broadcast (p_condvar);

#elif defined (WIN32)
    SetEvent (*p_condvar);

#endif
}


/*****************************************************************************
 * vlc_mutex_init: initialize a mutex
 *****************************************************************************/
int OS_mutex_init( OS_mutex_t *p_mutex )
{
#if defined( LINUX )
    pthread_mutexattr_t attr;
    int                 i_result;

    pthread_mutexattr_init( &attr );

# ifdef DEBUG
    /* Create error-checking mutex to detect problems more easily. */
#  if defined (__GLIBC__) && (__GLIBC_MINOR__ < 6)
    pthread_mutexattr_setkind_np( &attr, PTHREAD_MUTEX_ERRORCHECK_NP );
#  else
    pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_ERRORCHECK );
#  endif
# endif
    i_result = pthread_mutex_init( p_mutex, &attr );
    pthread_mutexattr_destroy( &attr );
    return i_result;

#elif defined( WIN32 )
    /* This creates a recursive mutex. This is OK as fast mutexes have
     * no defined behavior in case of recursive locking. */
    InitializeCriticalSection (&p_mutex->mutex);
    p_mutex->initialized = 1;
    return 0;

#endif
}







/**
 * Acquires a mutex. If needed, waits for any other thread to release it.
 * Beware of deadlocks when locking multiple mutexes at the same time,
 * or when using mutexes from callbacks.
 * This function is not a cancellation-point.
 *
 * @param p_mutex mutex initialized with vlc_mutex_init() or
 *                vlc_mutex_init_recursive()
 */
void OS_mutex_lock (OS_mutex_t *p_mutex)
{
#if defined(LINUX)
    int val = pthread_mutex_lock( p_mutex );


#elif defined( WIN32 )
    if (InterlockedCompareExchange (&p_mutex->initialized, 0, 0) == 0)
    { /* ^^ We could also lock super_mutex all the time... sluggish */
        assert (p_mutex != &super_mutex); /* this one cannot be static */

        OS_mutex_lock (&super_mutex);
        if (InterlockedCompareExchange (&p_mutex->initialized, 0, 0) == 0)
            OS_mutex_init (p_mutex);
        /* FIXME: destroy the mutex some time... */
        OS_mutex_unlock (&super_mutex);
    }
    assert (InterlockedExchange (&p_mutex->initialized, 1) == 1);
    EnterCriticalSection (&p_mutex->mutex);

#endif
}


/**
 * Acquires a mutex if and only if it is not currently held by another thread.
 * This function never sleeps and can be used in delay-critical code paths.
 * This function is not a cancellation-point.
 *
 * <b>Beware</b>: If this function fails, then the mutex is held... by another
 * thread. The calling thread must deal with the error appropriately. That
 * typically implies postponing the operations that would have required the
 * mutex. If the thread cannot defer those operations, then it must use
 * vlc_mutex_lock(). If in doubt, use vlc_mutex_lock() instead.
 *
 * @param p_mutex mutex initialized with vlc_mutex_init() or
 *                vlc_mutex_init_recursive()
 * @return 0 if the mutex could be acquired, an error code otherwise.
 */
int OS_mutex_trylock (OS_mutex_t *p_mutex)
{
#if defined(LINUX)
    int val = pthread_mutex_trylock( p_mutex );
    if (val != EBUSY){
        //OS_THREAD_ASSERT ("locking mutex");

    }
	return val;

#elif defined( WIN32 )
    if (InterlockedCompareExchange (&p_mutex->initialized, 0, 0) == 0)
    { /* ^^ We could also lock super_mutex all the time... sluggish */
        assert (p_mutex != &super_mutex); /* this one cannot be static */

        vlc_mutex_lock (&super_mutex);
        if (InterlockedCompareExchange (&p_mutex->initialized, 0, 0) == 0)
            vlc_mutex_init (p_mutex);
        /* FIXME: destroy the mutex some time... */
        vlc_mutex_unlock (&super_mutex);
    }
    assert (InterlockedExchange (&p_mutex->initialized, 1) == 1);
    return TryEnterCriticalSection (&p_mutex->mutex) ? 0 : EBUSY;

#endif
}

/**
 * Releases a mutex (or crashes if the mutex is not locked by the caller).
 * @param p_mutex mutex locked with vlc_mutex_lock().
 */
void OS_mutex_unlock (OS_mutex_t *p_mutex)
{
#if defined(LINUX)
    int val = pthread_mutex_unlock( p_mutex );
    //VLC_THREAD_ASSERT ("unlocking mutex");

#elif defined( WIN32 )
    assert (InterlockedExchange (&p_mutex->initialized, 1) == 1);
    LeaveCriticalSection (&p_mutex->mutex);

#endif
}



/**
 * Destroys a mutex. The mutex must not be locked.
 *
 * @param p_mutex mutex to destroy
 * @return always succeeds
 */
void OS_mutex_destroy (OS_mutex_t *p_mutex)
{
#if defined( LINUX )
    int val = pthread_mutex_destroy( p_mutex );
//    VLC_THREAD_ASSERT ("destroying mutex");

#elif defined( WIN32 )
    assert (InterlockedExchange (&p_mutex->initialized, -1) == 1);
    DeleteCriticalSection (&p_mutex->mutex);

#endif
}


/*****************************************************************************
 * vlc_cond_init: initialize a condition variable
 *****************************************************************************/
int OS_cond_init( OS_cond_t *p_condvar )
{
#if defined( LINUX )
    pthread_condattr_t attr;
    int ret;

    ret = pthread_condattr_init (&attr);
    if (ret)
        return ret;

# if !defined (_POSIX_CLOCK_SELECTION)
   /* Fairly outdated POSIX support (that was defined in 2001) */
#  define _POSIX_CLOCK_SELECTION (-1)
# endif
# if (_POSIX_CLOCK_SELECTION >= 0)
    /* NOTE: This must be the same clock as the one in mtime.c */
 //   pthread_condattr_setclock (&attr, CLOCK_MONOTONIC);
# endif

    ret = pthread_cond_init (p_condvar, &attr);
    pthread_condattr_destroy (&attr);
    return ret;

#elif defined( WIN32 )
    /* Create a manual-reset event (manual reset is needed for broadcast). */
    *p_condvar = CreateEvent( NULL, TRUE, FALSE, NULL );
    return *p_condvar ? 0 : ENOMEM;

#endif
}





/**
 * Destroys a condition variable. No threads shall be waiting or signaling the
 * condition.
 * @param p_condvar condition variable to destroy
 */
void OS_cond_destroy (OS_cond_t *p_condvar)
{
#if defined( LINUX )
    int val = pthread_cond_destroy( p_condvar );
 //   VLC_THREAD_ASSERT ("destroying condition");

#elif defined( WIN32 )
    CloseHandle( *p_condvar );

#endif
}



/**
 * Wakes up one thread waiting on a condition variable, if any.
 * @param p_condvar condition variable
 */
void OS_cond_signal (OS_cond_t *p_condvar)
{
#if defined( LINUX )
    int val = pthread_cond_signal( p_condvar );
//    VLC_THREAD_ASSERT ("signaling condition variable");

#elif defined( WIN32 )
    /* NOTE: This will cause a broadcast, that is wrong.
     * This will also wake up the next waiting thread if no thread are yet
     * waiting, which is also wrong. However both of these issues are allowed
     * by the provision for spurious wakeups. Better have too many wakeups
     * than too few (= deadlocks). */
    SetEvent (*p_condvar);

#endif
}





/**
 * Waits for a condition variable. The calling thread will be suspended until
 * another thread calls vlc_cond_signal() or vlc_cond_broadcast() on the same
 * condition variable, the thread is cancelled with vlc_cancel(), or the
 * system causes a "spurious" unsolicited wake-up.
 *
 * A mutex is needed to wait on a condition variable. It must <b>not</b> be
 * a recursive mutex. Although it is possible to use the same mutex for
 * multiple condition, it is not valid to use different mutexes for the same
 * condition variable at the same time from different threads.
 *
 * In case of thread cancellation, the mutex is always locked before
 * cancellation proceeds.
 *
 * The canonical way to use a condition variable to wait for event foobar is:
 @code
   vlc_mutex_lock (&lock);
   mutex_cleanup_push (&lock); // release the mutex in case of cancellation

   while (!foobar)
       vlc_cond_wait (&wait, &lock);

   --- foobar is now true, do something about it here --

   vlc_cleanup_run (); // release the mutex
  @endcode
 *
 * @param p_condvar condition variable to wait on
 * @param p_mutex mutex which is unlocked while waiting,
 *                then locked again when waking up.
 * @param deadline <b>absolute</b> timeout
 *
 * @return 0 if the condition was signaled, an error code in case of timeout.
 */
void OS_cond_wait (OS_cond_t *p_condvar, OS_mutex_t *p_mutex)
{
#if defined(LINUX)
    int val = pthread_cond_wait( p_condvar, p_mutex );
//    VLC_THREAD_ASSERT ("waiting on condition");

#elif defined( WIN32 )
    DWORD result;

    do
    {
     //   vlc_testcancel ();
        LeaveCriticalSection (&p_mutex->mutex);
        result = WaitForSingleObjectEx (*p_condvar, INFINITE, TRUE);
        EnterCriticalSection (&p_mutex->mutex);
    }
    while (result == WAIT_IO_COMPLETION);

    assert (result != WAIT_ABANDONED); /* another thread failed to cleanup! */
    assert (result != WAIT_FAILED);
    ResetEvent (*p_condvar);

#endif
}








// Printing

#define DEBUGFILENAME "DEBUGFILENAME.txt"

//extern LOG_Obj logTrace;


void DebugPrint(char *fmt,...){
#if defined(WIN32)
	va_list         list;
	char msg[256];

    va_start (list, fmt);
    vsprintf ((char*) msg , fmt, list);

    va_end (list);

	//DebugPrintf(msg);
	printf(msg);

#ifdef DEBUGTOFILE

	{
		FILE* fp=0;
		static int Initialize=0;
		//open file on HDD

	//open file on HDD
		if(!Initialize){
			if((fp = fopen(DEBUGFILENAME,"w+b"))==0){
		//printf("Cannot create Cebug file!\n");
			return ;
			}
			fclose(fp);
			Initialize =1;
		}
		if((fp = fopen(DEBUGFILENAME,"a+t"))==NULL)
		{
			//printf("Cannot open Cebug file!\n");
			return ;
		}

		fprintf(fp, msg);

		fclose(fp);
	}
#endif
#endif
}

void DebugReport(int maskid,char *fmt,...){
	va_list         list;
	char msg[1024];

    va_start (list, fmt);
    vsprintf ((char*) msg , fmt, list);

    va_end (list);

#ifdef DEBUGTOCONSOLE
	//DebugPrintf(msg);
	printf(msg);
#endif

#ifdef DEBUGTOFILE

	{
		FILE* fp=0;
		static int Initialize=0;
		//open file on HDD

	//open file on HDD
		if(!Initialize){
			if((fp = fopen(DEBUGFILENAME,"w+b"))==0){
		//printf("Cannot create Cebug file!\n");
			return ;
			}
			fclose(fp);
			Initialize =1;
		}
		if((fp = fopen(DEBUGFILENAME,"a+t"))==NULL)
		{
			//printf("Cannot open Cebug file!\n");
			return ;
		}

		fprintf(fp, msg);

		fclose(fp);
	}
#endif

}


static OS_Semaphore_t m_DebugPrintSem =0;

void DebugBlock(void){
	if(m_DebugPrintSem ==0){
		m_DebugPrintSem = OS_AllocSemaphore();
	}
	assert(m_DebugPrintSem !=0);
	OS_WaitSemaphore(m_DebugPrintSem );
}

void DebugRelease(void){
	assert(m_DebugPrintSem !=0);
	OS_SetSemaphore(m_DebugPrintSem );
}


void my_assert(int c){
	if(c==0){
		assert(c);
	}
}





int OS_Init(void){
#if defined(TI_BIOS)

#endif
return 0;
}






